package com.leyou.order.task;

import com.leyou.order.entity.Order;
import com.leyou.order.service.impl.OrderServiceImpl;
import io.lettuce.core.RedisClient;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class CloseOrderTask {

    @Autowired
    private OrderServiceImpl orderService;

    @Autowired
    private RedissonClient redissonClient;

    /**
     * 定时任务的频率，30分钟
     */
    private static final long TASK_INTERVAL = 1800000;
    /**
     * 定时任务的锁自动释放时间。 \r\n
     * 一般只要大于各服务器的时钟飘移时长+任务执行时长即可。\r\n
     * 此处默认120秒。\r\n
     */
    private static final long TASK_LEASE_TIME = 120;
    /**
     * 订单超时的期限，1小时
     */
    private static final int OVERDUE_SECONDS = 3600;

    private static final String LOCK_KEY = "close:order:task:lock";

    @Scheduled(fixedDelay = TASK_INTERVAL)
    public void closeOrder() {

            // 创建锁对象，并制定锁的名称
            RLock lock = redissonClient.getLock(LOCK_KEY);
            // 获取锁,设置自动失效时间为30s
        try {
            boolean isLock = lock.tryLock(0, TASK_LEASE_TIME, TimeUnit.SECONDS);
            // 判断是否获取锁
            if (!isLock) {
                /* 获取失败 */
                log.info("【清理订单任务】未能获取任务锁，结束任务。");
                return;
            }
            // 执行业务
            log.info("获取锁成功，执行定时任务。");
            List<Order> orders = orderService.queryOrderByStatus(1);
            ArrayList<Order> timoOutOrder = new ArrayList<>();
            orders.forEach(order -> {
                if (System.currentTimeMillis() - order.getCreateTime().getTime() > (2000)) {
                    timoOutOrder.add(order);
                }
            });
            orderService.closeOverdueOrders(timoOutOrder);
        } catch (Exception e) {
            log.error("【清理订单任务】获取任务锁异常，原因：{}", e.getMessage(), e);
        } finally {
            // 释放锁
            lock.unlock();
            log.info("【清理订单任务】任务执行完毕，释放锁。");
        }
    }

}
